package com.rem.redis.config;

import com.alibaba.fastjson.support.spring.FastJsonRedisSerializer;
import com.alibaba.fastjson.support.spring.GenericFastJsonRedisSerializer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.OxmSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.oxm.jaxb.Jaxb2Marshaller;

/**
 * @author Rem
 * @date 2022-03-09
 */


@EnableCaching
@Configuration
public class RedisConfig<K, V> {

    @Autowired
    RedisProperties redisProperties;

    /**
     * redis的序列化
     * * GenericToStringSerializer              可以将任何对象泛化为字符串并序列化
     * * JdkSerializationRedisSerializer        默认序列化对象 序列化java对象 存到redis中会存在乱码
     * * Jackson2JsonRedisSerializer            序列化object对象为json字符串 被序列化的对象如果带有泛型 反序列化会报错
     * * GenericJackson2JsonRedisSerializer     和Jackson2JsonRedisSerializer对比 效率低，占用内存高    会保存序列化的对象的包名和类名，反序列化时以这个作为标示就可以反序列化成指定的对象
     * * FastJsonRedisSerializer                ali出的序列化对象 和Jackson2JsonRedisSerializer类似
     * * GenericFastJsonRedisSerializer         ali出的序列化对象 和GenericJackson2JsonRedisSerializer
     * * OxmSerializer                          xml格式存储
     * * ByteArrayRedisSerializer
     * * StringRedisSerializer
     *
     * @param factory
     * @return
     */
    @Bean
    public RedisTemplate<K, V> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<K, V> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(factory);

        /**
         * String序列号配置 设置key hashkey
         */
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
        redisTemplate.setKeySerializer(stringRedisSerializer);
        redisTemplate.setHashKeySerializer(stringRedisSerializer);

        /**
         * Jackson2Json序列化配置 设置 value hash value
         */
        Jackson2JsonRedisSerializer<V> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>((Class<V>) Object.class);

        /**
         * GenericJackson2JsonRedisSerializer 设置 value hash value
         */
        GenericJackson2JsonRedisSerializer genericJackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
        FastJsonRedisSerializer<Object> fastJsonRedisSerializer = new FastJsonRedisSerializer<>(Object.class);
        GenericFastJsonRedisSerializer genericFastJsonRedisSerializer = new GenericFastJsonRedisSerializer();

        OxmSerializer oxmSerializer = new OxmSerializer(new Jaxb2Marshaller(), new Jaxb2Marshaller());

        //value和hash的value采用Json的序列化配置
        redisTemplate.setValueSerializer(genericJackson2JsonRedisSerializer);
        redisTemplate.setHashValueSerializer(genericJackson2JsonRedisSerializer);


        redisTemplate.setEnableTransactionSupport(true);

        return redisTemplate;
    }

}
